import { _decorator, BoxCollider, Camera, Color, Component, EventTouch, find, geometry, log, MeshRenderer, Node, PhysicsSystem, Script, SpriteRenderer, Tween, tween, TypeScript, v2, v3, Vec2, Vec3 } from 'cc';
import { GameManager, Group } from './GameManager';
import { UIManager } from './UIManager';
import { Player } from '../Player';
import { ZTool } from './ZTool';
import { Card } from '../Card';
import { Monster } from '../Monster';
import { AudioManager } from './AudioManager';
import Banner from './Banner';
const { ccclass, property } = _decorator;

const v3_cameraCurPos = v3();
const v3_cameraCurAg = v3();

@ccclass('PlayerController')
export class PlayerController extends Component {

    private static _instance: PlayerController = null;
    public static get Instance(): PlayerController {
        if (!this._instance) {
            this._instance = new PlayerController();
        }
        return this._instance;
    }

    PlayerScript: Player = null;

    v3_TargetCameraPos = v3();//摄像机目标位置
    v3_TargetCameraAg = v3();//摄像机目标角度
    IsShaking: boolean = false;
    CameraPosed = v3();

    onLoad() {
        PlayerController._instance = this;
        this.TakeOnTouch();
    }
    start() {
        v3_cameraCurPos.set(GameManager.Instance.MainCamera.position);
        v3_cameraCurAg.set(GameManager.Instance.MainCamera.eulerAngles);
    }

    TakeOnTouch() {
        this.node.on(Node.EventType.TOUCH_START, this.OnTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.OnTouchMove, this);
        this.node.on(Node.EventType.TOUCH_END, this.OnTouchEndOrCancel, this);
        this.node.on(Node.EventType.TOUCH_CANCEL, this.OnTouchEndOrCancel, this);
    }
    TakeOffTouch() {
        this.node.off(Node.EventType.TOUCH_START, this.OnTouchStart, this);
        this.node.off(Node.EventType.TOUCH_MOVE, this.OnTouchMove, this);
        this.node.off(Node.EventType.TOUCH_END, this.OnTouchEndOrCancel, this);
        this.node.off(Node.EventType.TOUCH_CANCEL, this.OnTouchEndOrCancel, this);
    }

    SetFinghtCardCollider(active: boolean) {
        for (let i = 0; i < GameManager.Instance.MainCamera.getChildByName("FightCardInit").children.length; i++) {
            GameManager.Instance.MainCamera.getChildByName("FightCardInit").children[i].getComponent(BoxCollider).enabled = active;
        }
        for (let i = 0; i < find("FightCardInit").children.length; i++) {
            find("FightCardInit").children[i].getComponent(BoxCollider).enabled = active;
        }
    }

    update(deltaTime: number) {
        if (GameManager.Instance.IsStart) {
            let worldPos = GameManager.Instance.PlayerInit.children[0].getWorldPosition();
            let PosX = ZTool.lerp(worldPos.x, this.EndPos, 0.1);
            if (PosX >= -2.5 && PosX <= 2.5) {
                if (!GameManager.Instance.IsEnterFight) {
                    GameManager.Instance.PlayerInit.children[0].setWorldPosition(v3(PosX, worldPos.y, worldPos.z));
                }
                if (GameManager.Instance.IsStart) {
                    let duration: number = 0;
                    if (GameManager.Instance.IsShaking) {
                        duration = 0.2;
                    }
                    else {
                        duration = 0.02;
                    }
                    Vec3.lerp(v3_cameraCurPos, v3_cameraCurPos, this.v3_TargetCameraPos, duration);
                    Vec3.lerp(v3_cameraCurAg, v3_cameraCurAg, this.v3_TargetCameraAg, duration);
                    GameManager.Instance.MainCamera.setPosition(v3(-PosX / 2 + v3_cameraCurPos.x, v3_cameraCurPos.y, v3_cameraCurPos.z));
                    GameManager.Instance.MainCamera.eulerAngles = v3(v3_cameraCurAg.x, 0, 0);
                }
            }

            if (this.deltaX > 0.5) {
                this.PlayerScript.TurnAngleByEuler(120);
            }
            else {
                if (this.deltaX < -0.5) {
                    this.PlayerScript.TurnAngleByEuler(240);
                }
                else {
                    this.PlayerScript.TurnAngleByEuler(180);
                }
            }
        }
        else {
            if (GameManager.Instance.IsShaking) {
                let duration = 0.2;
                Vec3.lerp(v3_cameraCurPos, v3_cameraCurPos, this.v3_TargetCameraPos, duration);
                GameManager.Instance.MainCamera.setPosition(v3(0 + v3_cameraCurPos.x, v3_cameraCurPos.y, v3_cameraCurPos.z));
            }
        }
    }

    RayHitPoint = v3();//射线打中的碰撞点
    Ray = new geometry.Ray();
    touchPos = v2();
    deltaX: number = 0;
    TouchCard: Node = null;
    OnTouchStart(event: EventTouch) {
        if (!GameManager.Instance.CanStart) return;
        this.touchPos = event.getLocation();
        if (!GameManager.Instance.IsStart && !GameManager.Instance.IsEnterFight) {
            GameManager.Instance.IsStart = true;
            UIManager.Instance.Main.active = false;
            UIManager.Instance.Running.active = true;
            this.PlayerScript.PlayerAni.crossFade("Run");
            let mainCamera = GameManager.Instance.MainCamera;
            this.v3_TargetCameraPos.set(0, mainCamera.position.y + 3, mainCamera.position.z + 1);
            this.v3_TargetCameraAg.set(-35, 0, 0);
            this.CameraPosed.set(this.v3_TargetCameraPos);
        }

        if (GameManager.Instance.IsEnterFight) {
            GameManager.Instance.EndArea.getChildByName("RayBox").active = false;
            GameManager.Instance.EndArea.getChildByName("RayBox").setPosition(v3(0, 5.08, 0));
            GameManager.Instance.EndArea.getChildByName("RayBox").active = true;
            //射线检测
            GameManager.Instance.MainCamera.getComponent(Camera).screenPointToRay(this.touchPos.x, this.touchPos.y, this.Ray);
            if (PhysicsSystem.instance.raycastClosest(this.Ray, 0xffffffff)) {
                let result = PhysicsSystem.instance.raycastClosestResult;
                if (result.collider.getGroup() == Group.Card) {
                    this.TouchCard = result.collider.node;
                    this.SetFinghtCardCollider(false);
                    this.TouchCard.setParent(find("FightCardInit"));
                    if (!this.TouchCard.getComponent(Card).CardBase) {
                        this.TouchCard.setWorldPosition(v3(result.hitPoint.x, 2, result.hitPoint.z));
                    }
                    this.TouchCard.eulerAngles = v3(-90, 0, 0);

                    for (let i in GameManager.Instance.PlayerInit.children[0].getComponent(Player).HaveMonsters) {
                        let monster = GameManager.Instance.PlayerInit.children[0].getComponent(Player).HaveMonsters[i];
                        if (this.TouchCard.getComponent(Card).Name == monster.getComponent(Monster).Name) {
                            monster.active = false;
                            if (this.TouchCard.getComponent(Card).CardBase) {
                                if (GameManager.Instance.GetLocalStorage("Level") == 4 || GameManager.Instance.GetLocalStorage("Level") == 9 || GameManager.Instance.GetLocalStorage("Level") == 14) {
                                    //boss关
                                    this.AllPower -= this.TouchCard.getComponent(Card).PriceValue;
                                    GameManager.Instance.ShowCardPower(GameManager.Instance.FinishEnv.getChildByName("CardBaseBoss").getChildByName("PlayerPower"), this.AllPower);
                                    let power: string = "";
                                    let enemyPower = GameManager.Instance.FinishEnv.getChildByName("CardBaseBoss").getChildByName("EnemyPower");
                                    for (let i = 0; i < enemyPower.children.length; i++) {
                                        power += enemyPower.children[i].getComponent(SpriteRenderer).spriteFrame.name;
                                    }
                                    if (this.AllPower < Number(power)) {
                                        GameManager.Instance.FinishEnv.getComponentInChildren(MeshRenderer).getMaterial(0).setProperty("albedo", Color.RED);
                                    }
                                    else {
                                        GameManager.Instance.FinishEnv.getComponentInChildren(MeshRenderer).getMaterial(0).setProperty("albedo", Color.GREEN);
                                    }
                                    UIManager.Instance.Fight.getChildByName("StartFightBtn").active = false;
                                }
                                else {
                                    this.TouchCard.getComponent(Card).CardBase.parent.getChildByName("BattleRoad").getChildByName("PlayerPower").destroyAllChildren();
                                    this.TouchCard.getComponent(Card).CardBase.parent.getChildByName("BattleRoad").getComponent(MeshRenderer).getMaterialInstance(0).setProperty("albedo", GameManager.Instance.CardBaseColor);
                                    UIManager.Instance.Fight.getChildByName("StartFightBtn").active = false;
                                }
                            }
                        }
                    }
                }
            }
            else {
                log("射线未打到")
            }
        }
    }
    EndPos: number = 0;
    IsCardBase: boolean = false;
    OnTouchMove(event: EventTouch) {
        if (!GameManager.Instance.IsEnterFight) {
            this.deltaX = (event.getLocation().x - this.touchPos.x) / 18;
            this.EndPos = GameManager.Instance.PlayerInit.children[0].getWorldPosition().x + this.deltaX;
            this.touchPos = event.getLocation();
        }
        else {
            if (this.TouchCard) {
                this.touchPos = event.getLocation();
                GameManager.Instance.EndArea.getChildByName("RayBox").active = false;
                GameManager.Instance.EndArea.getChildByName("RayBox").setPosition(v3(0, 5.08, 0));
                GameManager.Instance.EndArea.getChildByName("RayBox").active = true;
                //射线检测
                GameManager.Instance.MainCamera.getComponent(Camera).screenPointToRay(this.touchPos.x, this.touchPos.y, this.Ray);
                if (PhysicsSystem.instance.raycastClosest(this.Ray, 0xffffffff)) {
                    let result = PhysicsSystem.instance.raycastClosestResult;
                    if (result.collider.getGroup() == Group.CardBase) {
                        if (!this.IsCardBase) {
                            this.IsCardBase = true;
                            this.TouchCard.scale = Vec3.ZERO;
                            tween(this.TouchCard)
                                .to(0.5, { scale: Vec3.ONE }, { easing: "backOut" })
                                .start()
                            GameManager.Instance.CardSetNum++;
                        }
                        this.TouchCard.getComponent(Card).CardBase = result.collider.node;
                        if (this.TouchCard.getComponent(Card).CardTop.active) this.TouchCard.getComponent(Card).CardTop.active = false;
                        if (this.TouchCard.getComponent(Card).CardRole.active) this.TouchCard.getComponent(Card).CardRole.active = false;
                        this.TouchCard.setWorldPosition(result.collider.node.getChildByName("Pos").getWorldPosition());
                    }
                    else {
                        if (this.IsCardBase) {
                            this.IsCardBase = false;
                            Tween.stopAllByTarget(this.TouchCard);
                            this.TouchCard.scale = Vec3.ONE;
                        }
                        if (this.TouchCard.getComponent(Card).CardBase) {
                            this.TouchCard.getComponent(Card).CardBase.getComponent(BoxCollider).enabled = true;
                            this.TouchCard.getComponent(Card).CardBase = null;
                            GameManager.Instance.CardSetNum--;
                        }
                        if (!this.TouchCard.getComponent(Card).CardTop.active) this.TouchCard.getComponent(Card).CardTop.active = true;
                        if (!this.TouchCard.getComponent(Card).CardRole.active) this.TouchCard.getComponent(Card).CardRole.active = true;
                        this.TouchCard.setWorldPosition(v3(result.hitPoint.x, 2, result.hitPoint.z));
                    }
                }
            }
        }
    }

    AllPower: number = 0;
    OnTouchEndOrCancel(event: EventTouch) {
        if (!GameManager.Instance.IsEnterFight) {
            this.deltaX = 0;
        } else {
            if (this.TouchCard) {
                if (this.IsCardBase) {
                    this.TouchCard.getChildByName("Card").getComponentInChildren(MeshRenderer).getMaterialInstance(0).setProperty("rimLightStrengthen", 10);
                    for (let i in GameManager.Instance.PlayerInit.children[0].getComponent(Player).HaveMonsters) {
                        let monster = GameManager.Instance.PlayerInit.children[0].getComponent(Player).HaveMonsters[i];
                        if (this.TouchCard.getComponent(Card).Name == monster.getComponent(Monster).Name) {
                            let worldPos = v3(this.TouchCard.getWorldPosition().x, this.TouchCard.getWorldPosition().y + 0.05, this.TouchCard.getWorldPosition().z);
                            monster.setWorldPosition(worldPos);
                            let enemyPower;
                            if (GameManager.Instance.GetLocalStorage("Level") == 4 || GameManager.Instance.GetLocalStorage("Level") == 9 || GameManager.Instance.GetLocalStorage("Level") == 14) {
                                enemyPower = GameManager.Instance.FinishEnv.getChildByName("CardBaseBoss").getChildByName("EnemyPower");
                            }
                            else {
                                enemyPower = this.TouchCard.getComponent(Card).CardBase.parent.getChildByName("BattleRoad").getChildByName("EnemyPower");
                            }
                            let power: string = "";
                            for (let i = 0; i < enemyPower.children.length; i++) {
                                power += enemyPower.children[i].getComponent(SpriteRenderer).spriteFrame.name;
                            }

                            if (GameManager.Instance.GetLocalStorage("Level") == 4 || GameManager.Instance.GetLocalStorage("Level") == 9 || GameManager.Instance.GetLocalStorage("Level") == 14) {
                                this.AllPower += this.TouchCard.getComponent(Card).PriceValue;
                                if (this.AllPower < Number(power)) {
                                    GameManager.Instance.FinishEnv.getComponentInChildren(MeshRenderer).getMaterial(0).setProperty("albedo", Color.RED);
                                }
                                else {
                                    GameManager.Instance.FinishEnv.getComponentInChildren(MeshRenderer).getMaterial(0).setProperty("albedo", Color.GREEN);
                                }
                                GameManager.Instance.ShowCardPower(GameManager.Instance.FinishEnv.getChildByName("CardBaseBoss").getChildByName("PlayerPower"), this.AllPower);
                                if (GameManager.Instance.CardSetNum >= 3) {
                                    UIManager.Instance.Fight.getChildByName("StartFightBtn").active = true;
                                    Banner.Instance.ShowNativeAd();
                                }
                            }
                            else {
                                let battleRoad = this.TouchCard.getComponent(Card).CardBase.parent.getChildByName("BattleRoad");
                                if (this.TouchCard.getComponent(Card).PriceValue > Number(power)) {
                                    battleRoad.getComponent(MeshRenderer).getMaterialInstance(0).setProperty("albedo", Color.GREEN);
                                }
                                else {
                                    if (this.TouchCard.getComponent(Card).PriceValue < Number(power)) {
                                        battleRoad.getComponent(MeshRenderer).getMaterialInstance(0).setProperty("albedo", Color.RED);
                                    }
                                    else {
                                        battleRoad.getComponent(MeshRenderer).getMaterialInstance(0).setProperty("albedo", Color.GRAY);
                                    }
                                }
                                GameManager.Instance.ShowCardPower(this.TouchCard.getComponent(Card).CardBase.parent.getChildByName("BattleRoad").getChildByName("PlayerPower"), this.TouchCard.getComponent(Card).PriceValue);
                                if (GameManager.Instance.CardSetNum >= find("EnemyFightInit").children.length) {
                                    UIManager.Instance.Fight.getChildByName("StartFightBtn").active = true;
                                    Banner.Instance.ShowNativeAd();
                                }
                            }

                            AudioManager.Instance.playSound("Audio/Init");
                            monster.getComponent(Monster).MonsterAni.crossFade("Jump");
                            GameManager.Instance.PlayerMonsters[this.TouchCard.getComponent(Card).CardBase.parent.getSiblingIndex()] = monster;
                            monster.getComponent(Monster).FightPoint = this.TouchCard.getComponent(Card).CardBase.parent.getChildByName("FightPoint2").getWorldPosition();
                            monster.active = true;

                            break;
                        }
                    }
                    this.TouchCard.getComponent(Card).CardBase.getComponent(BoxCollider).enabled = false;
                    this.SetFinghtCardCollider(true);
                    this.TouchCard = null;
                }
                else {
                    this.TouchCard.setParent(GameManager.Instance.MainCamera.getChildByName("FightCardInit"));
                    this.TouchCard.setPosition(this.TouchCard.getComponent(Card).CardPosed);
                    this.TouchCard.eulerAngles = this.TouchCard.getComponent(Card).CardAngled;

                    if (this.TouchCard.getComponent(Card).CardBase) {
                        this.TouchCard.getComponent(Card).CardBase.getComponent(BoxCollider).enabled = true;
                        this.TouchCard.getComponent(Card).CardBase = null;
                    }

                    if (!this.TouchCard.getComponent(Card).CardTop.active) this.TouchCard.getComponent(Card).CardTop.active = true;
                    if (!this.TouchCard.getComponent(Card).CardRole.active) this.TouchCard.getComponent(Card).CardRole.active = true;
                    this.SetFinghtCardCollider(true);
                    this.TouchCard = null;
                }
            }
        }
    }
}


